﻿using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using PSE.Deployment.SetupBase.Configuration;

namespace PSE.Deployment.ConfigurationManager.Controls
{
	/// <summary>
	/// Classe que instancia um controle GroupBox atrelado à XmlTags
	/// </summary>
	public class SimpleGroupBox : GroupBox
	{
		private SimpleGroupBox()
		{
			this.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
			this.VerticalAlignment = System.Windows.VerticalAlignment.Top;
		}

		/// <summary>
		/// Construtor que prepara o controle visual através dos parametros informados
		/// </summary>
		/// <param name="allTags">Lista de todas as Tags disponíveis no momento</param>
		/// <param name="tag">Tag que se deseja atrelar ao controle SimpleGroupBox</param>
		/// <param name="simpleGroupBoxes">Controle pai do tipo SimpleGroupBoxes que deve ser informado para controlar 
		/// a paternidade de seus subitens que são do tipo SimpleGroupBox</param>
		public SimpleGroupBox(List<XmlTag> allTags, XmlTag tag, SimpleGroupBoxes sgb)
			: this()
		{
			Grid gbGrid = new Grid();
			ColumnDefinition cDef1 = new ColumnDefinition();
			ColumnDefinition cDef2 = new ColumnDefinition();

            cDef1.Width = GridLength.Auto;
            cDef2.Width = GridLength.Auto;

			gbGrid.ColumnDefinitions.Add(cDef1);
			gbGrid.ColumnDefinitions.Add(cDef2);

			this.Header = tag.Description;
			this.Margin = new Thickness(10, 0, 0, 0);

			//-------------------------------------------------------

			#region ATTRIBUTES
			if (tag.Attributes != null && tag.Attributes.Count > 0)
			{
				RowDefinition removeButtonRowDef = new RowDefinition();
				removeButtonRowDef.Height = new GridLength(1, GridUnitType.Auto);
				gbGrid.RowDefinitions.Add(removeButtonRowDef);

				RemoveTagButton btRemove = new RemoveTagButton(allTags, tag, sgb, this);
				btRemove.SetValue(Grid.RowProperty, 0);
				btRemove.SetValue(Grid.ColumnProperty, 1);
				btRemove.SetValue(Grid.ColumnSpanProperty, 2);
				btRemove.HorizontalAlignment = HorizontalAlignment.Right;

				gbGrid.Children.Add(btRemove);

				int contador = 1;

				foreach (XmlAttribute attribute in tag.Attributes)
				{
					RowDefinition attribRowDef = new RowDefinition();
					attribRowDef.Height = new GridLength(25, GridUnitType.Pixel);
					gbGrid.RowDefinitions.Add(attribRowDef);

					SimpleLabel lblName = new SimpleLabel(attribute.Description, HorizontalAlignment.Right, VerticalAlignment.Top);

					Control txtValue = this.DecideCustomControl(attribute);

					lblName.SetValue(Grid.RowProperty, contador);
					lblName.SetValue(Grid.ColumnProperty, 0);
                    lblName.HorizontalAlignment = HorizontalAlignment.Left;

					txtValue.SetValue(Grid.RowProperty, contador);
					txtValue.SetValue(Grid.ColumnProperty, 1);
					txtValue.HorizontalAlignment = HorizontalAlignment.Left;

					gbGrid.Children.Add(lblName);
					gbGrid.Children.Add(txtValue);

					contador++;
				}
			}
			#endregion

			this.Content = gbGrid;
		}

		/// <summary>
		/// Método que retorna um CustomControl dependendo do tipo do Atributo informado no parametro
		/// </summary>
		/// <param name="attribute">Atributo que se deseja instanciar visualmente</param>
		/// <returns>Retorna uma classe do tipo Control</returns>
		Control DecideCustomControl(XmlAttribute attribute)
		{
			switch (attribute.Type)
			{
				case PSE.Deployment.SetupBase.Configuration.Enums.XmlTagType.String:
					return new SimpleTextBox(attribute);
				case PSE.Deployment.SetupBase.Configuration.Enums.XmlTagType.Uri:
					return new UriTextBox(attribute);
				case PSE.Deployment.SetupBase.Configuration.Enums.XmlTagType.Endpoint:
                    return new EndPointTextBox(attribute);
                case PSE.Deployment.SetupBase.Configuration.Enums.XmlTagType.EndpointPort:
                    return new Int32TextBox(attribute);
				case PSE.Deployment.SetupBase.Configuration.Enums.XmlTagType.Integer:
					return new Int32TextBox(attribute);
				case PSE.Deployment.SetupBase.Configuration.Enums.XmlTagType.Password:
					return new PasswordTextBox(attribute);
				//PasswordTextBox pwdControl = new PasswordTextBox(attribute);
				//return pwdControl.RetrievePasswordBox();
				case PSE.Deployment.SetupBase.Configuration.Enums.XmlTagType.Boolean:
					return new SimpleCheckBox(attribute);
				default:
					return new SimpleTextBox(attribute);
			}
		}
	}

	/// <summary>
	/// Classe que instancia um control Grid atrelado SimpleGroupBox
	/// </summary>
	public class SimpleGroupBoxes : Grid
	{
		Grid gridAddButton = null;
		internal int GRID_GROUP_BOXES_ROW_COUNTER = 1;

		public SimpleGroupBoxes()
		{
			this.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
			this.VerticalAlignment = System.Windows.VerticalAlignment.Top;
		}

		/// <summary>
		/// Construtor do controle SimpleGroupBoxes que através dos parametros instancia classes do tipo GroupBox
		/// </summary>
		/// <param name="allTags">Todas as tags disponiveis no XmlFile</param>
		/// <param name="tags">Tags que se deseja acrescentar no controle</param>
		public SimpleGroupBoxes(List<XmlTag> allTags, List<XmlTag> tags)
			: this()
		{
			//const int MIN_ITEMS_INSIDE_GRID = 2;

			if (tags != null && tags.Count > 0)
			{
				if (gridAddButton == null)
				{
					AddTagButton atb = new AddTagButton(allTags, tags[0], this);
					atb.SetValue(Grid.RowProperty, 0);

					RowDefinition gridAddButtonRowDef = new RowDefinition();
					gridAddButtonRowDef.Height = new GridLength(1, GridUnitType.Auto);

					this.RowDefinitions.Add(gridAddButtonRowDef);
					this.Children.Add(atb);
				}

				foreach (XmlTag tag in tags)
				{
					RowDefinition rDef = new RowDefinition();
					rDef.Height = new GridLength(1, GridUnitType.Auto);
					this.RowDefinitions.Add(rDef);

					SimpleGroupBox sgb = new SimpleGroupBox(allTags, tag, this);
					sgb.SetValue(Grid.RowProperty, this.GRID_GROUP_BOXES_ROW_COUNTER);

					this.Children.Add(sgb);
					this.GRID_GROUP_BOXES_ROW_COUNTER++;
				}

				this.ForbidAllowLastItemRemoval();
			}
		}

		/// <summary>
		/// Metodo responsavel por habilitar ou nao o botao de remover um GroupBox filho
		/// </summary>
		/// <param name="isEnabled">Informa se o controle deve ser habilitado ou não</param>
		internal void ForbidAllowLastItemRemoval()
		{
			RemoveTagButton lastRemoveButton = null;
			int totalRemoveButtons = 0;

			foreach (UIElement ue in this.Children)
			{
				if (ue is SimpleGroupBox)
				{
					SimpleGroupBox sgb = (SimpleGroupBox)ue;
					foreach (UIElement childUe in ((Grid)sgb.Content).Children)
					{
						if (childUe is RemoveTagButton)
						{
							if (lastRemoveButton == null)
								lastRemoveButton = ((RemoveTagButton)childUe);

							((RemoveTagButton)childUe).IsEnabled = true;

							totalRemoveButtons++;
						}
					}
				}
			}

			if (totalRemoveButtons == 1 && lastRemoveButton != null)
				lastRemoveButton.IsEnabled = false;
		}
	}
}